package com.quark.service;

import com.quark.mapper.system.SysUserMapper;
import com.quark.mapper.system.SysUserRoleMapper;
import com.quark.model.system.menu.MenuTreeVO;
import com.quark.model.system.user.AdminUser;
import com.quark.model.system.user.SysUser;
import com.quark.model.system.user.SysUserRole;
import com.quark.service.redis.RedisService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 张高昌
 * @date 2021/11/14 19:07
 * @description TODO
 */
@Service
@RequiredArgsConstructor
public class UmsAdminServiceImpl implements UserDetailsService {

    private final SysUserMapper sysUserMapper;

    private final SysUserRoleMapper sysUserRoleMapper;

    private final RedisService redisService;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        SysUser sysUser = (SysUser) redisService.get("sys_user:" + userName);
        if (sysUser == null) {
            sysUser = sysUserMapper.selectByUserName(userName);
            redisService.set("sys_user:" + userName, sysUser, 14400);
        }
        if (sysUser == null) {
            throw new UsernameNotFoundException("用户不存在！");
        }

        AdminUser adminUser = new AdminUser();
        adminUser.setId(sysUser.getId());
        adminUser.setUsername(sysUser.getUserName());
        adminUser.setPassword(sysUser.getPassword());

        this.getRoles(sysUser.getId(), adminUser);

        return adminUser;
    }

    /**
     * 获取所属角色
     *
     * @param userId
     * @param adminUser
     */
    public void getRoles(Long userId, AdminUser adminUser) {
        List<SysUserRole> userRoleList = (List<SysUserRole>) redisService.get("sys_user_role:" + userId);
        if (userRoleList == null) {
            userRoleList = sysUserRoleMapper.selectUserRoleList(userId);
            redisService.set("sys_user_role:" + userId, userRoleList, 14400);
        }

        List<Integer> collect1 = userRoleList.stream().map(SysUserRole::getRId).collect(Collectors.toList());
        List<String> authorities = (List<String>) redisService.get("sys_user_authorities:" + userId);
        if (authorities == null) {
            authorities = sysUserRoleMapper.selectPathByUserId(collect1);
            redisService.set("sys_user_authorities:" + userId, authorities, 14400);
        }

        List<String> list = new LinkedList<>();
        for (SysUserRole sysUserRole : userRoleList) {
            list.add("ROLE_" + sysUserRole.getRId());
        }

        authorities.addAll(list);

        adminUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(
                String.join(",", authorities)
        ));
    }
}
